{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Single-Qubit Gates Tutorial Workbook\n",
    "\n",
    "**What is this workbook?**\n",
    "A workbook is a collection of problems, accompanied by solutions to them. \n",
    "The explanations focus on the logical steps required to solve a problem; they illustrate the concepts that need to be applied to come up with a solution to the problem, explaining the mathematical steps required. \n",
    "\n",
    "Note that a workbook should not be the primary source of knowledge on the subject matter; it assumes that you've already read a tutorial or a textbook and that you are now seeking to improve your problem-solving skills. You should attempt solving the tasks of the respective kata first, and turn to the workbook only if stuck. While a textbook emphasizes knowledge acquisition, a workbook emphasizes skill acquisition.\n",
    "\n",
    "This workbook describes the solutions to the problems offered in the [Single-Qubit Gates tutorial](./SingleQubitGates.ipynb). \n",
    "Since the tasks are offered as programming problems, the explanations also cover some elements of Q# that might be non-obvious for a first-time user.\n",
    "\n",
    "**What you should know for this workbook**\n",
    "\n",
    "You should be familiar with the following concepts before tackling the Single-Qubit Gates tutorial (and this workbook):\n",
    "1. Basic linear algebra\n",
    "2. The concept of qubit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 1</span>: The $Y$ gate\n",
    "\n",
    "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n",
    "\n",
    "**Goal:** Apply the $Y$ gate to the qubit, i.e., transform the given state into $i\\alpha|1\\rangle - i\\beta|0\\rangle$.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "We have to do exactly what the task asks us to do: apply the Pauli gate $Y=\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}$.\n",
    "\n",
    "This has the effect of turning $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$ into $Y|\\psi\\rangle = i\\alpha|1\\rangle - i\\beta|0\\rangle$, which in matrix form looks as follows:\n",
    "\n",
    "$$ \\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix} \\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} = \\begin{bmatrix} -i\\beta \\\\ i\\alpha \\end{bmatrix}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T1_ApplyY\n",
    "\n",
    "operation ApplyY (q : Qubit) : Unit is Adj+Ctl {\n",
    "    Y(q); // As simple as that\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 1 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-1:-The-$Y$-gate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 2</span>: Applying a global phase $i$\n",
    "\n",
    "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n",
    "\n",
    "**Goal:** Use several Pauli gates to change the qubit state to $i|\\psi\\rangle = i\\alpha|0\\rangle + i\\beta|1\\rangle$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "We need to apply a gate which applies a global phase of $i$, i.e. $|\\psi\\rangle \\rightarrow i|\\psi\\rangle$.  \n",
    "The matrix representation of such a gate is $\\begin{bmatrix} i & 0 \\\\ 0 & i \\end{bmatrix} = i\\begin{bmatrix} 1 & 0 \\\\ 0 & 1 \\end{bmatrix} = iI$.  \n",
    "Since we are restricted to the Pauli gates, we use the property that a product of any two distinct Pauli gates equals the third gate with a $+i$ or a $-i$ global phase: $-iXYZ=I$. This can be restated as $XYZ = iI$.\n",
    "$$\\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix}\\begin{bmatrix} 0 & -i \\\\ i & 0 \\end{bmatrix}\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix} = \\begin{bmatrix} i & 0 \\\\ 0 & i \\end{bmatrix}$$\n",
    "\n",
    "> Remember the rightmost gates in mathematical notation are applied first in Q# code. Hence we first apply the $Z$ gate, followed by the $Y$ gate and finally the $X$ gate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T2_GlobalPhaseI\n",
    "\n",
    "operation GlobalPhaseI (q : Qubit) : Unit is Adj+Ctl {\n",
    "    Z(q);\n",
    "    Y(q);\n",
    "    X(q);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 2 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-2:-Applying-a-global-phase-$i$)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <a name=\"exercise-3\"></a> <span style=\"color:blue\">Exercise 3</span>*: Applying a $-1$ phase to $|0\\rangle$ state\n",
    "\n",
    "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n",
    "\n",
    "**Goal:** Use several Pauli gates to change the qubit state to $- \\alpha|0\\rangle + \\beta|1\\rangle$, i.e., apply the transformation represented by the following matrix::\n",
    "\n",
    "$$\\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$$\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "The first thing to notice is that the gate $\\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$ is quite similar to the Pauli $Z$ gate $\\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix}$. \n",
    "The only difference being that the negative phase is applied on the $|0\\rangle$ instead of $|1\\rangle$. Hence we can simulate this gate by switching $|0\\rangle$ and $|1\\rangle$ states, applying the Pauli $Z$ gate and switching them back. The Pauli $X$ gate (also called the $NOT$ gate or the bit flip gate) is the perfect gate to flip the state of the qubit and to undo the action afterwards. \n",
    "\n",
    "Hence we can express the $Z_0 = \\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix}$ matrix as \n",
    "\n",
    "$$ Z_0 = \\begin{bmatrix} -1 & 0 \\\\ 0 & 1 \\end{bmatrix} = \\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & -1 \\end{bmatrix} \\begin{bmatrix} 0 & 1 \\\\ 1 & 0 \\end{bmatrix} = XZX$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T3_SignFlipOnZero\n",
    "\n",
    "operation SignFlipOnZero (q : Qubit) : Unit is Adj+Ctl {\n",
    "    X(q); // Flip the qubit\n",
    "    Z(q); // Apply negative phase on the |1> state\n",
    "    X(q); // Flip the qubit back\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 3 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-3*:-Applying-a-$-1$-phase-to-$|0\\rangle$-state)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 4</span>: Preparing a $|-\\rangle$ state\n",
    "\n",
    "**Input:** A qubit in state $|0\\rangle$.\n",
    "\n",
    "**Goal:** Transform the qubit into state $|-\\rangle$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "We know that applying the Hadamard gate $H$ on the computational basis states $|0\\rangle$ and $|1\\rangle$ results in Hadamard basis states $|+\\rangle$ and $|-\\rangle$, respectively.\n",
    "We are given a qubit in the state $|0\\rangle$. We first apply the Pauli $X$ gate to turn it into $X|0\\rangle=|1\\rangle$, and then apply the $H$ gate, turning the qubit into the required $H|1\\rangle=|-\\rangle$ state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T4_PrepareMinus\n",
    "\n",
    "operation PrepareMinus (q : Qubit) : Unit is Adj+Ctl {\n",
    "    X(q); // Turn |0> into |1>\n",
    "    H(q); // Turn |1> into |->\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 4 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-4:-Preparing-a-$|-\\rangle$-state)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 5</span>: Three-fourths phase\n",
    "\n",
    "**Input:** A qubit in an arbitrary state $|\\psi\\rangle = \\alpha|0\\rangle + \\beta|1\\rangle$.\n",
    "\n",
    "**Goal:** Use several phase shift gates to apply the transformation represented by the following matrix to the given qubit:\n",
    "\n",
    "$$\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{3i\\pi/4} \\end{bmatrix}$$\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "The three-fourths phase gate above can be expressed as a product of 2 canonical gates - the $T$ gate is $\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix}$ and the $S$ gate is $\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/2} \\end{bmatrix}$.\n",
    "\n",
    "$$\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i3\\pi/4} \\end{bmatrix} \n",
    "= \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/2} \\end{bmatrix} \n",
    "= \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\begin{bmatrix} 1 & 0 \\\\ 0 & i \\end{bmatrix} = TS$$\n",
    "\n",
    "Note that $TS = ST$, so it doesn't matter in what order to apply those gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T5_ThreeQuatersPiPhase\n",
    "\n",
    "operation ThreeQuatersPiPhase (q : Qubit) : Unit is Adj+Ctl {\n",
    "    S(q);\n",
    "    T(q);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 5 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-5:-Three-fourths-phase)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 6</span>: Preparing a rotated state\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. Real numbers $\\alpha$ and $\\beta$ such that $\\alpha^2 + \\beta^2 = 1$.\n",
    "3. A qubit in state $|0\\rangle$.\n",
    "\n",
    "**Goal:** Use a rotation gate to transform the qubit into state $\\alpha|0\\rangle -i\\beta|1\\rangle$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "We use the rotation gate $R_x(\\theta)$. This gate turns the state $|0\\rangle$ into $R_x(\\theta)|0\\rangle = \\cos\\frac{\\theta}{2}|0\\rangle - i\\sin\\frac{\\theta}{2}|1\\rangle$.  \n",
    "This is similar to the state we need. We just need to find an angle $\\theta$ such that $\\cos\\frac{\\theta}{2}=\\alpha$ and $\\sin\\frac{\\theta}{2}=\\beta$. We can use these two equations to solve for $\\theta$: $\\theta = 2\\arctan\\frac{\\beta}{\\alpha}$. (*Note: It is given that $\\alpha^2 + \\beta^2=1$*).  \n",
    "Hence the required gate is $R_x(2\\arctan\\frac{\\beta}{\\alpha})$, which in matrix form is \n",
    "$\\begin{bmatrix} \\alpha & -i\\beta \\\\ -i\\beta & \\alpha \\end{bmatrix}$.  \n",
    "This gate turns $|0\\rangle = \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix}$ into $\\begin{bmatrix} \\alpha & -i\\beta \\\\ -i\\beta & \\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix} = \\begin{bmatrix} \\alpha \\\\ -i\\beta \\end{bmatrix} = \\alpha|0\\rangle -i\\beta|1\\rangle$.\n",
    "\n",
    "> Trigonometric functions are available in Q# via [Math](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math) namespace. In this case we will need [ArcTan2](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan2)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T6_PrepareRotatedState\n",
    "\n",
    "open Microsoft.Quantum.Math;\n",
    "\n",
    "operation PrepareRotatedState (alpha : Double, beta : Double, q : Qubit) : Unit is Adj+Ctl {\n",
    "    Rx(2.0 * ArcTan2(beta, alpha), q);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 6 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-6:-Preparing-a-rotated-state)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span style=\"color:blue\">Exercise 7</span>**: Preparing an arbitrary state\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. A non-negative real number $\\alpha$.\n",
    "2. A non-negative real number $\\beta = \\sqrt{1 - \\alpha^2}$.\n",
    "3. A real number $\\theta$.\n",
    "4. A qubit in state $|0\\rangle$.\n",
    "\n",
    "**Goal:** Transform the qubit into state $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.\n",
    "\n",
    "> Since only the relative amplitudes and relative phase have any physical meaning, this allows us to prepare any single-qubit quantum state we want to."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Solution \n",
    "\n",
    "This exercise can be done in two steps. \n",
    "\n",
    "1. Convert the state from $|0\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.  \n",
    "   This can be done similar to the Exercise 6, by first preparing an $\\alpha|0\\rangle -i\\beta|1\\rangle$ state using $R_x$ gate, and then removing the relative phase of $-i$ by applying the $S$ gate, which would turn $\\alpha|0\\rangle -i\\beta|1\\rangle$ to $\\alpha|0\\rangle + \\beta|1\\rangle$.  \n",
    "   An alternative, simpler approach is to use the $R_y$ gate, which allows us to get the necessary state right away without introducing a relative phase: \n",
    "$$R_y(2\\arctan\\frac{\\beta}{\\alpha}) = \\begin{bmatrix} \\alpha & -\\beta \\\\ \\beta & \\alpha \\end{bmatrix}$$\n",
    "2. Add a phase of $e^{i\\theta}$ to the $|1\\rangle$ basis state using the $R_1(\\theta)$ gate. This would turn $\\alpha|0\\rangle +\\beta|1\\rangle$ to $\\alpha|0\\rangle + e^{i\\theta}\\beta|1\\rangle$.\n",
    "\n",
    "The solution can be represented as $R_1(\\theta)R_y(2\\arctan\\frac{\\beta}{\\alpha})$ or in matrix form as \n",
    "$$\\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i\\theta} \\end{bmatrix}\n",
    "\\begin{bmatrix} \\alpha & -\\beta \\\\ \\beta & \\alpha \\end{bmatrix} = \n",
    "\\begin{bmatrix} \\alpha & -\\beta \\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix}$$\n",
    "\n",
    "This turns $|0\\rangle = \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix}$ into \n",
    "$\\begin{bmatrix} \\alpha & -\\beta \\\\ e^{i\\theta}\\beta & e^{i\\theta}\\alpha \\end{bmatrix} \\begin{bmatrix} 1 \\\\ 0\\end{bmatrix} = \n",
    "\\begin{bmatrix} \\alpha \\\\ e^{i\\theta}\\beta \\end{bmatrix} = \\alpha|0\\rangle +e^{i\\theta}\\beta|1\\rangle$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T7_PrepareArbitraryState\n",
    "\n",
    "open Microsoft.Quantum.Math;\n",
    "\n",
    "operation PrepareArbitraryState (alpha : Double, beta : Double, theta : Double, q : Qubit) : Unit is Adj+Ctl {\n",
    "    Ry(2.0 * ArcTan2(beta, alpha), q); // Step 1\n",
    "    R1(theta, q); // Step 2\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Return to exercise 7 of the Single-Qubit Gates tutorial.](./SingleQubitGates.ipynb#Exercise-7**:-Preparing-an-arbitrary-state)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion\n",
    "\n",
    "Congratulations! You have learned enough to try solving the first part of the [Basic Gates kata](../../BasicGates/BasicGates.ipynb). \n",
    "When you are done with that, you can continue to the next tutorials in the series to learn about the [multi-qubit systems](../MultiQubitSystems/MultiQubitSystems.ipynb) and the [multi-qubit gates](../MultiQubitGates/MultiQubitGates.ipynb)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Q#",
   "language": "qsharp",
   "name": "iqsharp"
  },
  "language_info": {
   "file_extension": ".qs",
   "mimetype": "text/x-qsharp",
   "name": "qsharp",
   "version": "0.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
